#include <iostream>
#include <stdio.h>
#include <assert.h>
#include <cstdlib>

typedef int SlistDataType;

typedef struct SListNode
{
    SlistDataType data;
    struct SListNode* next;
}SListNode;

void SlistNodePrint(SListNode* plist)
{
    SListNode* cur = plist;
    while(cur != nullptr)
    {
        printf("%d ", cur->data);
        cur = cur->next;
    }
    printf("NULL\n");
}

SListNode* BuySlistNode(SlistDataType x)
{
    SListNode* Node = (SListNode*)malloc(sizeof(SListNode));
    if(Node == nullptr)
    {
        printf("malloc node fail");
        return nullptr;
    }

    Node->data = x;
    Node->next = nullptr;
    return Node;
}

void SListNodePushFront(SListNode** plist, SlistDataType x)
{
    SListNode* newnode = BuySlistNode(x);
    newnode->next = *plist;
    *plist = newnode;
}

void SListNodePushBack(SListNode** plist, SlistDataType x)
{
    SListNode* newnode = BuySlistNode(x);
    if(*plist == nullptr)
    {
        *plist = newnode;
    }
    else
    {
        SListNode* tail = *plist;
        while(tail->next != nullptr)
        {
            tail = tail->next;
        }
        tail->next = newnode;
    }
}

void SListNodeInsertAfter(SListNode* pos, SlistDataType x)
{
    assert(pos);
    SListNode* newnode = BuySlistNode(x);
    newnode->next = pos->next;
    pos->next = newnode;
}

void SListNodeInsertFront(SListNode** plist, SListNode* pos, SlistDataType x)
{
    assert(pos);
    SListNode* newnode = BuySlistNode(x);
    if(pos == *plist)
    {
        newnode->next = pos;
        *plist = newnode;
    }
    else
    {
        SListNode* prev = *plist;
        while(prev->next != pos)
        {
            prev = prev->next;
        }
        newnode->next = prev->next;
        prev->next = newnode;
    }
}

void SListNodePopFront(SListNode** plist)
{
    if(*plist == nullptr)
    {
        return;
    }
    else
    {
        SListNode* tmp = *plist;
        *plist = (*plist)->next;
        free(tmp);
        tmp = nullptr;
    }
}

void SListNodePopBack(SListNode** plist)
{
    if(*plist == nullptr)
    {
        return;
    }
    else if((*plist)->next == nullptr)
    {
        free(*plist);
        *plist = nullptr;
    }
    else
    {
        SListNode* prev = *plist;
        SListNode* tail = (*plist)->next;
        while(tail->next != nullptr)
        {
            prev = tail;
            tail = tail->next;
        }
        free(tail);
        tail = nullptr;
        prev->next = nullptr;
    }
}

void SListNodePopAfter(SListNode* pos)
{
    assert(pos);
    if(pos->next == nullptr) return;
    pos->next = pos->next->next;
    free(pos->next);
    pos->next = nullptr;
}

void SListNodePopCur(SListNode** plist, SListNode* pos)
{
    assert(pos);
    if(pos == *plist)
    {
        *plist = pos->next;
        free(pos);
        pos = nullptr;
    }
    else
    {
        SListNode* prev = *plist;
        while(prev->next != pos)
        {
            prev = prev->next;
        }
        prev->next = pos->next;
        free(pos);
        pos = nullptr;
    }
}

SListNode* SListNodeFind(SListNode* plist, SlistDataType x)
{
    SListNode* cur = plist;
    while(cur != nullptr)
    {
        if(cur->data == x)
        {
            return cur;
        }
        cur = cur->next;
    }
    return nullptr;
}

SListNode* SListNodeModify(SListNode* pos, SlistDataType x)
{
    pos->data = x;
}